using System.Threading;
using System.Windows.Media;
using Roslyn.Compilers.CSharp;
using Roslyn.Services;
using Roslyn.Services.Editor;

namespace Roslyn.Refactoring.Library
{
    internal class ExtractParameterAction : ICodeAction
    {
        private readonly ICodeActionEditFactory _editFactory;
        private readonly IDocument _document;
        private readonly ExpressionSyntax _expressionToken;
        private readonly MethodDeclarationSyntax _methodDeclarationSyntax;

        public ExtractParameterAction(ICodeActionEditFactory editFactory, IDocument document, ExpressionSyntax expressionToken, MethodDeclarationSyntax methodDeclarationSyntax)
        {
            _editFactory = editFactory;
            _document = document;
            _expressionToken = expressionToken;
            _methodDeclarationSyntax = methodDeclarationSyntax;
        }

        public ICodeActionEdit GetEdit(CancellationToken cancellationToken = new CancellationToken())
        {
            var oldTree = (SyntaxTree)_document.GetSyntaxTree(cancellationToken);
            var semantic = _document.GetSemanticModel(cancellationToken);

            var newType =
                semantic.GetSemanticInfo(_expressionToken, cancellationToken).Type.ToMinimalDisplayString(
                    oldTree.GetLocation(_methodDeclarationSyntax), (SemanticModel)semantic);

            var extractor = new ExtractParameterRewriter()
                                {
                                    DeclarationNode = _methodDeclarationSyntax,
                                    ExpressionNode = _expressionToken,
                                    NewType = newType, 
                                    VariableName = "TODO"
                                };
            var newRoot = extractor.Visit(oldTree.Root);
            return _editFactory.CreateTreeTransformEdit(_document.Project.Solution, oldTree, newRoot);
        }

        public ImageSource Icon
        {
            get { return null; }
        }

        public string Description
        {
            get { return "Extract parameter"; }
        }
    }
}